/**
 *
 */
package com.angel.dao.generic.helpers;

import java.util.Date;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;

import com.angel.dao.generic.exceptions.HibernateConfigurationException;

/** Helps you at the Hibernate functionality. It offers you many services relationated with Hibernate configuration, session
 * and sessionFactory objects.
 *
 * @author William
 */
public class HibernateHelper {

	private static final Logger LOGGER = Logger.getLogger(HibernateHelper.class);
	private static final ThreadLocal<Session> session = new ThreadLocal<Session>();

	private static SessionFactory sessionFactory;
	private static Configuration configuration;

	private static Boolean annotationsConfiguration = true;

	private HibernateHelper() {
		super();
	}

	/** Get current session at hibernate context. Default it is initialized with annotations configuration.
	 * Set annotations configuration to false, if you want initialize hbm configuration.
	 *
	 * @return current session configured.
	 */
	public static Session getCurrentSession(){
		Session s = (Session) session.get();
		if (s == null) {
			if(!annotationsConfiguration){
				LOGGER.info("Creating session factory at " + new Date());
				createSessionFactory();
			} else {
				LOGGER.info("Creating annotation session factory at " + new Date());
				createAnnotationSessionFactory();
			}
			try {
				LOGGER.info("Opening session.");
				s = sessionFactory.openSession();
			} catch (HibernateException e) {
				LOGGER.error("Error opening hibernate session: Caused by: '" + e.getCause() + "'.");
				throw new HibernateConfigurationException(e);
			}
			session.set(s);
		}
		return s;
	}

	public static boolean isInitialized() {
		return session.get() != null;
	}


	public static boolean isLoadedSession() {
		return isInitialized() && session.get().isOpen();
	}

	private static void createAnnotationSessionFactory(){
		if (sessionFactory == null) {
			initializeAnnotationConfiguration();
			sessionFactory = configuration.buildSessionFactory();
		}
	}

	private static void createSessionFactory(){
		if (sessionFactory == null) {
			initializeConfiguration();
			sessionFactory = configuration.buildSessionFactory();
		}
	}

	/** Initialize xml Hibernate configuration file.
	 *
	 */
	public static void initializeConfiguration(){
		if(configuration == null){
			configuration = new Configuration();
		}
		configuration.configure();
	}


	public static void initializeAnnotationConfiguration(){
		if(configuration == null){
			configuration = new AnnotationConfiguration();
		}
		configuration.configure();
	}

	/**
	 * @param annotationsConfiguration the annotationsConfiguration to set
	 */
	public static void setAnnotationsConfiguration(Boolean annotationsConfiguration) {
		HibernateHelper.annotationsConfiguration = annotationsConfiguration;
	}
}
